﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Interop;
using ChatCam.skin;
using ChatCam.Gui;
using NATP2P.UDPNat;
using System.IO;
using MetriCam;
using System.Windows.Threading;
using System.Threading;
using System.Drawing.Imaging;
using NetFwTypeLib;
namespace ChatCam
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private WebCam camera;
        public MainWindow()
        {
            InitializeComponent();
            camera = new WebCam();
            AuthorizeProgram("ChatWebCam", ".\\ChatCam.exe",
                NET_FW_SCOPE_.NET_FW_SCOPE_ALL,
                NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY);
        }
        #region skin and gui configuration
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            // This can’t be done any earlier than the SourceInitialized event:
            GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
            // Attach a window procedure in order to detect later enabling of desktop 
            // composition
            IntPtr hwnd = new WindowInteropHelper(this).Handle;
            HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));
        }
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_DWMCOMPOSITIONCHANGED)
            {
                // Reenable glass:
                GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
                handled = true;
            }
            return IntPtr.Zero;
        }
        private const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
        public bool AuthorizeProgram(string title, string path,
          NET_FW_SCOPE_ scope, NET_FW_IP_VERSION_ ipver)
        {
            Type type = Type.GetTypeFromProgID("HNetCfg.FwAuthorizedApplication");
            INetFwAuthorizedApplication authapp = Activator.CreateInstance(type)
                as INetFwAuthorizedApplication;
            authapp.Name = title;
            authapp.ProcessImageFileName = path;
            authapp.Scope = scope;
            authapp.IpVersion = ipver;
            authapp.Enabled = true;

            INetFwMgr mgr = WinFirewallManager();
            try
            {
                mgr.LocalPolicy.CurrentProfile.AuthorizedApplications.Add(authapp);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.Write(ex.Message);
                return false;
            }
            return true;
        }
        public static INetFwMgr WinFirewallManager()
        {
            Type type = Type.GetTypeFromCLSID(
                new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}"));
            return Activator.CreateInstance(type) as INetFwMgr;
        }
        private void btnAbout_Click(object sender, RoutedEventArgs e)
        {
            About about = new About();
            about.Owner = this;
            about.ShowDialog();
        }

        #endregion

        UDPNatSocket conhandler;
        private void btnConfigt_Click(object sender, RoutedEventArgs e)
        {
            Config config = new Config();
            config.Owner = this;
            config.ShowDialog();
            try
            {
                conhandler = config.ConHandler;
                conhandler.RaiseNewDatagramEvent += new EventHandler<NewDatagramEventArgs>(conhandler_RaiseNewDatagramEvent);
            }
            catch (Exception msg)
            {

                MessageBox.Show("No connection happen\n" + msg.Message);
            }

        }

        void conhandler_RaiseNewDatagramEvent(object sender, NewDatagramEventArgs e)
        {
            MemoryStream ms = new MemoryStream(e.Data);
            System.Drawing.Bitmap ii = new System.Drawing.Bitmap(System.Drawing.Image.FromStream(ms));

            // Swebcam.Source = ImageProcess.loadBitmap(ii);
            Dispatcher.BeginInvoke(DispatcherPriority.Normal,
                         (Action)(() => Swebcam.Source = ImageProcess.loadBitmap(ii)));


        }

        public delegate void WebCamDelegate(ImageSource s);

        DispatcherTimer timer;
        DateTime dt = new DateTime();
        int s;
        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            if (!camera.IsConnected())
            {
                camera.Connect();
                timer = new DispatcherTimer();
                timer.Tick += new EventHandler(timer_Tick);
                timer.Interval = new TimeSpan(0, 0, 1);
                timer.Start();
                ThreadPool.QueueUserWorkItem(SendVideoStream);
            }
        }
        void timer_Tick(object sender, EventArgs e)
        {
            s++;

            textBlock1.Text = dt.AddSeconds(s).TimeOfDay.ToString();
        }
        private void SendVideoStream(object o)
        {
            try
            {
                bool continueCalculating = true;
                while (continueCalculating)
                {
                    System.IO.MemoryStream ms = new System.IO.MemoryStream();

                    camera.Update();
                    camera.CalcBitmap().Save(ms, ImageFormat.Png);
                    Dispatcher.BeginInvoke(DispatcherPriority.Normal,
                              (Action)(() => Rwebcam.Source = ImageProcess.loadBitmap(camera.CalcBitmap()))
                              );

                    System.Drawing.Image gg = ImageProcess.ScaleImage(System.Drawing.Image.FromStream(ms), 250, 250);
                    conhandler.Send(ImageProcess.CompressImage(gg, 20).ToArray());
                    ms.Dispose();
                    Thread.Sleep(100);

                }
            }
            catch (Exception msg)
            {
                timer.Stop();
                MessageBox.Show(msg.StackTrace, msg.Message);
            }
             

        }


    }
}
